﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Cloud.Boss.Models;
using Cloud.Core.Cache;
using Cloud.Dto.Sys;
using Cloud.Framework.Filter;
using Cloud.Framework.Model;
using Cloud.Service.Account;
using Cloud.Service.Log;
using Cloud.Utility;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;

namespace Cloud.Boss.Controllers
{
    public class AccountController : BaseController
    {
        private readonly IAccountService _accountService;
        private readonly ICacheManager _cacheManager;
        public AccountController(IOptions<ProjectSetting> _projectSetting, ILogService _logService, IAccountService _accountService, ICacheManager _cacheManager) : base(_projectSetting, _logService)
        {
            this._accountService = _accountService;
            this._cacheManager = _cacheManager;
        }
        [NoLogAction]
        [PublicAction]
        public IActionResult GetValidateCode()
        {
            var vc = ValidateCodeHelper.GetValidateCode();
            var value = CryptHelper.EncryptMD5(vc.ValidateNum.ToLower());
            HttpContext.Response.Cookies.Append("boss_login_validate_code", value, new CookieOptions
            {
                Expires = DateTime.Now.AddMinutes(1),
                HttpOnly = true
            });
            byte[] bs = vc.ImgStream;
            return File(bs, @"image/Png");
        }
        [HttpGet]
        [PublicAction]
        public IActionResult Login(string nodeid = null, string error = null)
        {
            ViewBag.nodeid = nodeid;
            ViewBag.error = error;
            //var conf= (IConfiguration)HttpContext.RequestServices.GetService(typeof(IConfiguration));
            //ViewBag.safeAddress= conf.GetSection("ProjectSetting")["SafeIPAddress"];
            var currentIp = HttpContext.Connection.RemoteIpAddress.ToString();
            ViewBag.safeAddress = _projectSetting.Value.SafeIPAddress.Split(",").Any(c => c == currentIp);
            ViewBag.title = _projectSetting.Value.SystemName;
            return View();
        }
        [HttpPost]
        [PublicAction]
        [NoWriteLogParametersAction]
        public ActionResult Login(string name, string password, string validateCode = null)
        {
            //是否是安全IP地址
            var currentIp = HttpContext.Connection.RemoteIpAddress.ToString();
            bool isSafeIp = _projectSetting.Value.SafeIPAddress.Split(",").Any(c => c == currentIp);
            if (isSafeIp == false)
            {
                if (string.IsNullOrEmpty(validateCode))
                {
                    return ErrorJsonResult("请输入验证码");
                }
                validateCode = CryptHelper.EncryptMD5(validateCode.ToLower());
                string code = null;
                Request.Cookies.TryGetValue("boss_login_validate_code", out code);
                if (string.IsNullOrEmpty(code))
                {
                    return ErrorJsonResult("验证码过期，请刷新验证码");
                }

                if (code != validateCode)
                {
                    return ErrorJsonResult("验证码错误");
                }
            }

            var sr = _accountService.Login(name, password);
            if (!sr.IsSucceed)
            {
                return ErrorJsonResult(sr.Message);
            }

            string cookieKey = _projectSetting.Value.CookieKey;
            string cookieValue = Guid.NewGuid().ToString();//每一个登录用户生成不同的cookie
            //写入cookie           
            HttpContext.Response.Cookies.Append(cookieKey, cookieValue, new CookieOptions
            {
                Expires = DateTime.Now.AddMinutes(_projectSetting.Value.SessionTimeOut),
                HttpOnly = true
            });

            //将用户权限以cookieValue为键写入cache
            string userCacheKey = cookieValue;
            //当前登录用户
            var currentSysUser = new CurrentSysUser();
            currentSysUser.LoginID = sr.Data.LoginID;
            currentSysUser.LoginName = sr.Data.LoginName;
            currentSysUser.RelName = sr.Data.RelName;
            currentSysUser.IsAdmin = sr.Data.IsAdmin;
            currentSysUser.PermissionCacheKey = Guid.NewGuid().ToString();//权限key

            //滑动过期时间
            _cacheManager.Add(userCacheKey, currentSysUser, new TimeSpan(0, _projectSetting.Value.SessionTimeOut, 0), true);

            var permission = _accountService.GetCurrentUserPermission(sr.Data.LoginID, sr.Data.IsAdmin);
            _cacheManager.Add(currentSysUser.PermissionCacheKey, permission.Data.Select(c => new CurrentSysUserPermission()
            {
                action = c.action,
                controller = c.controller,
                id = c.id,
                name = c.name,
                parentId = c.parentId,
                url = c.url
            }).ToList(), new TimeSpan(0, _projectSetting.Value.SessionTimeOut, 0), true);

            return SuccessJsonResult();
        }

        [HttpGet]
        [LoginAction]
        public IActionResult Logout()
        {
            //清除权限信息
            string pKey = CurrentSysUser.PermissionCacheKey;
            _cacheManager.Remove(pKey);
            var cookieKey = _projectSetting.Value.CookieKey;
            string cookieValue = null;
            Request.Cookies.TryGetValue(cookieKey, out cookieValue);
            //清除用户缓存信息
            _cacheManager.Remove(cookieValue);
            //TODO:清除cookie            
            HttpContext.Response.Cookies.Append(cookieKey, cookieValue, new CookieOptions
            {
                Expires = DateTime.Now.AddMinutes(-30),
                HttpOnly = true
            });

            return RedirectToAction("Login");
        }

        [HttpGet]
        [LoginAction]
        public IActionResult ModifyPassword()
        {
            return View();
        }
        [HttpPost]
        [LoginAction]
        [AutoValidateAntiforgeryToken]
        public async Task<IActionResult> ModifyPassword(string oldPwd, string newPwd, string newPwd1)
        {
            ModifyPasswordDto model = new ModifyPasswordDto()
            {
                LoginId = CurrentSysUser.LoginID,
                OldPwd = oldPwd,
                NewPwd = newPwd,
                NewPwd1 = newPwd1
            };
            var result= await _accountService.ModifyPassword(model);
            if (result.IsSucceed)
            {
                return SuccessJsonResult();
            }
            return ErrorJsonResult(result.Message);

        }
    }
}